import tkinter as tk
from tkinter import ttk
import json
from tkinter.filedialog import asksaveasfilename, askopenfilename
from tkinter.messagebox import showerror
import time


class ConfigWindow(tk.Tk):
    def __init__(self):
        # 创建窗口
        super().__init__()
        self.title("Config")
        self.entry_box = {}
        self.model_para = {}

        self.resizable(False, False)
        self.create_widgets()
        self.protocol('WM_DELETE_WINDOW', self.event_skip_button)

    def create_widgets(self):
        try:
            f = open('temp.json', 'r')
        except IOError:
            # default para
            self.model_para['Alg'] = '相对响应'
            self.model_para['background'] = '0.0'
            self.model_para['threshold'] = '0.0'
            self.model_para['factor'] = '0.3'
            self.model_para['mode'] = 'single'
            self.model_para['channels'] = ['1']
        else:
            self.model_para = json.load(f)
            f.close()

        self.model_para['switch'] = 'off'

        # 在主窗口上添加一个frame控件
        frame_gbl = tk.Frame(self)
        frame_gbl.pack()

        # 框框一
        frame_1 = tk.LabelFrame(frame_gbl, text="计算方式")
        frame_1.grid(row=0, column=0, sticky=tk.EW)

        tk.Label(frame_1, text='计算方式').grid(row=0, column=0, sticky=tk.W, padx=10, pady=10)

        # 创建下拉菜单
        self.cbox_method = ttk.Combobox(frame_1, state='readonly')
        # 设置下拉菜单中的值
        self.cbox_method['value'] = '相对响应'
        # 通过 current() 设置下拉菜单选项的默认值
        self.cbox_method.current(0)
        self.cbox_method.grid(row=0, column=1, sticky=tk.E, padx=5, pady=5)

        # 框框二
        frame_2 = tk.LabelFrame(frame_gbl, text="参数设置(范围-2.3uA ~ 2.3uA)")
        frame_2.grid(row=1, column=0, sticky=tk.EW)

        tk.Label(frame_2, text='背景电流').grid(row=0, column=0, sticky=tk.E, padx=5, pady=5)

        tk.Label(frame_2, text="uA", font=('Arial', '12', 'bold')).grid(row=0, column=2)

        okay_cmd = self.register(self.entry_check)

        self.entry_1 = ttk.Entry(frame_2, validate='focus', validatecommand=(okay_cmd, 'entry1'))

        self.entry_1.grid(row=0, column=1, sticky=tk.E, padx=5, pady=5)

        self.entry_box['entry1'] = [self.entry_1, self.model_para['background']]

        tk.Label(frame_2, text='电流阈值').grid(row=1, column=0, sticky=tk.E, padx=5, pady=5)

        tk.Label(frame_2, text="uA", font=('Arial', '12', 'bold')).grid(row=1, column=2)

        self.entry_2 = ttk.Entry(frame_2, validate='focusout', validatecommand=(okay_cmd, 'entry2'))

        self.entry_2.grid(row=1, column=1, sticky=tk.E, padx=5, pady=5)

        self.entry_box['entry2'] = [self.entry_2, self.model_para['threshold']]

        tk.Label(frame_2, text='相对响应系数').grid(row=2, column=0, sticky=tk.E, padx=5, pady=5)

        self.entry_3 = ttk.Entry(frame_2, validate='focusout', validatecommand=(okay_cmd, 'entry3'))

        self.entry_3.grid(row=2, column=1, sticky=tk.E, padx=5, pady=5)

        self.entry_box['entry3'] = [self.entry_3, self.model_para['factor']]

        # 框框三 按钮选项
        frame_3 = tk.LabelFrame(frame_gbl, text="选项")
        frame_3.columnconfigure(2)
        frame_3.rowconfigure(1)
        frame_3.grid(row=3, column=0, sticky=tk.EW)
        start_button = tk.Button(frame_3, text='启用模型', width=15, command=self.event_start_button)
        start_button.grid(row=0, column=0, sticky=tk.W, padx=10)
        skip_button = tk.Button(frame_3, text='关闭模型', width=15, command=self.event_skip_button)
        skip_button.grid(row=0, column=1, sticky=tk.E, padx=10)
        load_button = tk.Button(frame_3, text='载入模型', width=15, command=self.event_load_button)
        load_button.grid(row=1, column=0, sticky=tk.W, padx=10)
        save_button = tk.Button(frame_3, text='保存模型', width=15, command=self.event_save_button)
        save_button.grid(row=1, column=1, sticky=tk.E, padx=10)

        # 框框四 通道选择
        frame_4 = tk.LabelFrame(frame_gbl, text="测量通道")
        frame_4.grid(row=2, column=0, sticky=tk.EW)

        self.channel = tk.StringVar()
        self.single_radio_btn = tk.Radiobutton(frame_4, text='单通道', variable=self.channel, value='single',
                                               command=self.channel_check)
        self.single_radio_btn.grid(row=0, column=0, sticky=tk.E, padx=10)

        self.cbox_channel = ttk.Combobox(frame_4, state='readonly')
        self.cbox_channel.config(state=tk.DISABLED)
        self.cbox_channel['value'] = ['1', '2', '3', '4', '5', '6', '7', '8']
        self.cbox_channel.grid(row=0, column=1, sticky=tk.E, padx=5, pady=5)

        self.multi_radio_btn = tk.Radiobutton(frame_4, text='多通道', variable=self.channel, value='multi',
                                              command=self.channel_check)
        self.multi_radio_btn.grid(row=1, column=0, sticky=tk.E, padx=10)
        frame_checkbox = tk.Frame(frame_4)
        frame_checkbox.grid(row=1, column=1)
        self.multi_var = []
        self.channels_option = []
        for i in range(8):
            self.multi_var.append(tk.IntVar())
            self.channels_option.append(
                tk.Checkbutton(frame_checkbox, text=i + 1, variable=self.multi_var[-1], onvalue=1, offvalue=0,
                               command=self.channel_check))
            self.channels_option[-1].grid(row=i // 4, column=i % 4)

        self.channel.set(self.model_para['mode'])

        # self.channel_check()
        self.display_para()

    def event_skip_button(self):
        self.model_para['switch'] = 'off'
        info_json = json.dumps(self.model_para, sort_keys=False, indent=4, separators=(',', ':'))
        f = open('temp.json', 'w')
        f.write(info_json)
        f.close()
        self.destroy()
        return

    def event_start_button(self):
        if self.get_para() == 0:
            return
        self.destroy()
        return

    def event_load_button(self):
        name = askopenfilename(filetypes=[('tmod', '*.tmod')], initialdir='.')
        # print(name)

        if name == '':
            return

        f = open(name, 'r')
        self.model_para = json.load(f)
        f.close()
        self.model_para['switch'] = 'off'
        self.display_para()
        return

    def event_save_button(self):
        name = asksaveasfilename(defaultextension='.tmod', initialdir='.')
        if name == '':
            return
        try:
            f = open(name, 'w')
        except TypeError:
            return
        else:
            model_para_json = self.get_para()
            f.write(model_para_json)
            f.close()
        return

    def get_para(self):
        self.model_para['Alg'] = self.cbox_method.get()
        self.model_para['background'] = float(self.entry_1.get())
        self.model_para['threshold'] = float(self.entry_2.get())
        self.model_para['factor'] = float(self.entry_3.get())
        self.model_para['switch'] = 'on'
        self.model_para['mode'] = self.channel.get()
        ch_list = []
        if self.model_para['mode'] == 'single':
            ch_list.append(self.cbox_channel.get())
        elif self.model_para['mode'] == 'multi':
            for i in range(8):
                if self.multi_var[i].get() == 1:
                    ch_list.append(str(i + 1))
            if len(ch_list) == 0:
                showerror(message='通道选择错误')
                return 0
        self.model_para['channels'] = ch_list

        info_json = json.dumps(self.model_para, sort_keys=False, indent=4, separators=(',', ':'))
        f = open('temp.json', 'w')
        f.write(info_json)
        f.close()
        # f = open('temp.json', 'r')
        # info_data = json.load(f)
        # f.close()
        return info_json

    def entry_check(self, cho):
        value = '0'
        pre = self.entry_box[cho][1]
        value = self.entry_box[cho][0].get()
        try:
            value = float(value)
        except ValueError as e:
            value = self.entry_box[cho][1]
            self.entry_box[cho][0].delete(0, 99)
            self.entry_box[cho][0].insert(0, value)
            self.entry_box[cho][0].config(foreground='red')
            return False
        else:
            if value < -2.3 or value > 2.3:
                # print('wrong')
                value = self.entry_box[cho][1]
                self.entry_box[cho][0].delete(0, 99)
                self.entry_box[cho][0].insert(0, value)
                self.entry_box[cho][0].config(foreground='red')
                return False

        # print('right')
        self.entry_box[cho][1] = value
        self.entry_box[cho][0].config(foreground='black')
        return True

    def channel_check(self):
        if self.channel.get() == 'single':
            self.cbox_channel.config(state=tk.NORMAL)
            self.cbox_channel.config(state='readonly')
            if self.cbox_channel.get() == '':
                self.cbox_channel.current(0)
            for e in self.channels_option:
                e.config(state=tk.DISABLED)
        elif self.channel.get() == 'multi':
            self.cbox_channel.config(state=tk.DISABLED)
            nothing = 1
            for e in self.channels_option:
                e.config(state=tk.NORMAL)

    def display_para(self):
        self.entry_1.insert(0, self.model_para['background'])
        self.entry_2.insert(0, self.model_para['threshold'])
        self.entry_3.insert(0, self.model_para['factor'])
        if self.model_para['mode'] == 'single':
            self.channel.set('single')
            self.channel_check()
            self.cbox_channel.current(int(self.model_para['channels'][-1]) - 1)
        elif self.model_para['mode'] == 'multi':
            self.channel.set('multi')
            self.channel_check()
            for i in self.model_para['channels']:
                self.channels_option[int(i) - 1].select()


if __name__ == "__main__":
     win = ConfigWindow()
     win.mainloop()
